package com.mlnx.netty.base.handler;


import com.mlnx.analysis.filter.FilterManager;
import com.mlnx.data.entity.BpInfo;
import com.mlnx.device.pojo.dto.EcgDeviceDto;
import com.mlnx.device.service.CallBack;
import com.mlnx.device.session.core.DeviceSession;
import com.mlnx.device.session.core.EcgDeviceSession;
import com.mlnx.device.session.core.MpDeviceSession;
import com.mlnx.device.session.core.XmbpDeviceSession;
import com.mlnx.mptp.ResponseCode;
import com.mlnx.mptp.model.ecg.ECGChannelType;
import com.mlnx.mptp.model.ecg.ECGDeviceRunMode;
import com.mlnx.mptp.mptp.MpPacket;
import com.mlnx.netty.base.message.RegisterMessage;
import com.mlnx.netty.base.message.XmbpCacheMessage;
import com.mlnx.netty.base.utils.MacUtils;
import com.mlnx.tp.base.model.DeviceType;
import com.mlnx.tp.base.utils.LogUtils;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;

import java.util.Date;
import java.util.List;

public class RegisterHandle extends
        BaseSimpleChannelInboundHandler<RegisterMessage> {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx,
                                RegisterMessage registerMessage) throws Exception {

        String deviceId = registerMessage.getDeviceId();
        DeviceType deviceType = registerMessage.getDeviceType();

        if (deviceId == null) {
            log.error("注册的时候缺少  deviceID ");
            return;
        }

        switch (registerMessage.getDeviceType()) {
            case ECG_DEVICE:
                deviceNettyService.getEcgDevice(registerMessage.getDeviceId(), new CallBack<EcgDeviceDto>() {
                    @Override
                    public void onBack(EcgDeviceDto ecgDeviceDto) {

                        if (!ctx.channel().isActive()) {
                            log.error("设备{} 已经断开连接", ecgDeviceDto.getNumeration());
                            return;
                        }

                        ecgRegister(ctx, registerMessage.getKeepAliveTimer(), registerMessage.getDeviceId(),
                                ecgDeviceDto);
                    }
                });
                break;
            case BP_DEVICE:
            case SBP_DEVICE:
            case MP_DEVICE:
            case XM_BP:
                if (registerMessage.getDeviceType().equals(DeviceType.MP_DEVICE)) {
                    log.info("mp设备:" + deviceId + "  注册");
                } else if (registerMessage.getDeviceType().equals(DeviceType.XM_BP)) {
                    log.info("xmbp设备:" + deviceId + "  注册");
                }

                deviceNettyService.getPatientId(deviceId, new CallBack<Integer>() {
                    @Override
                    public void onBack(Integer patientId) {

                        if (!ctx.channel().isActive()) {
                            log.error("设备{} 已经断开连接", deviceId);
                            return;
                        }

                        if (patientId == null) {
                            LogUtils.e(String.format("%s 设备未绑定患者 注册失败", deviceId));
                        } else {
                            DeviceSession session = null;

                            if (registerMessage.getDeviceType().equals(DeviceType.MP_DEVICE)) {
                                session = new MpDeviceSession(deviceId);
                                session.setPatientId(patientId);
                                session.setDeviceType(DeviceType.MP_DEVICE);
                                log.info("MP设备:" + deviceId + "注册成功:" + ctx.channel().toString());

                            } else if (registerMessage.getDeviceType().equals(DeviceType.XM_BP)) {
                                session = new XmbpDeviceSession(deviceId);
                                session.setPatientId(patientId);
                                session.setDeviceType(DeviceType.XM_BP);
                                List<BpInfo> bpInfos = deviceNettyService.getXmbpCache(ctx.channel());
                                if (bpInfos != null) {
                                    XmbpCacheMessage xmbpCacheMessage = new XmbpCacheMessage();
                                    xmbpCacheMessage.setBpInfos(bpInfos);
                                    ctx.channel().writeAndFlush(xmbpCacheMessage);
                                }


                                log.info("XMBP设备:" + deviceId + "注册成功:" + ctx.channel().toString());
                            }

                            session.setDeviceType(DeviceType.XM_BP);
                            addSession(ctx, session, registerMessage.getKeepAliveTimer());
                        }
                    }
                });
                break;
            default:
                log.error("设备类型非法 ：" + deviceType);
        }
    }

    private void ecgRegister(ChannelHandlerContext ctx, Integer keepAliveTimer, String deviceId,
                             EcgDeviceDto ecgDevice) {

        if (ecgDevice == null) {
            LogUtils.e(String.format("%s 设备不存在", deviceId));
            MpPacket packet = new MpPacket().registerAck(DeviceType.SERVER,
                    ResponseCode.NOT_EXIST_DEVICE);
            ctx.channel().writeAndFlush(packet);
            return;
        }

        if (ecgDevice.getPatientId() == null || ecgDevice.getPatientId() == 0) {
            log.error(String.format("%s 设备未绑定患者", deviceId));
            MpPacket packet = new MpPacket().registerAck(DeviceType.SERVER,
                    ResponseCode.UN_BIND_PATIENT);
            ctx.channel().writeAndFlush(packet);
        } else {
            int type = 0;

            EcgDeviceSession session = new EcgDeviceSession(deviceId, MacUtils.getMcuId(ecgDevice.getCpuId()));
            session.setPatientId(ecgDevice.getPatientId());

            switch (ecgDevice.getEcgDeviceRunMode()) {
                case DIAGNOSIS_MODE:
                    ((EcgDeviceSession) session).getAnalysis().setEcgFilter(FilterManager.getDiagnosisEcgFilter());
                    break;
                case STANDARD_MODE:
                    ((EcgDeviceSession) session).getAnalysis().setEcgFilter(FilterManager.getStandardEcgFilter());
                    break;
                case SPORT_MODE:
                    ((EcgDeviceSession) session).getAnalysis().setEcgFilter(FilterManager.getSportEcgFilter());
                    break;
                default:
            }

            session.setDeviceType(DeviceType.ECG_DEVICE);
            addSession(ctx, session, keepAliveTimer);

            ECGChannelType ecgChannelType = ECGChannelType.decode(ecgDevice.getEcgChannelType().getCode());
            ECGDeviceRunMode ecgDeviceRunMode = ECGDeviceRunMode.decode(ecgDevice.getEcgDeviceRunMode().getCode());

            MpPacket packet = new MpPacket().registerAck(ecgChannelType, ecgDeviceRunMode, DeviceType.SERVER,
                    ecgDevice.getPatientId(), ResponseCode.SUCESS);

            ctx.channel().writeAndFlush(packet);
            ctx.channel().writeAndFlush(new MpPacket().startEcg());
            LogUtils.i("心电设备:" + deviceId + "注册成功:" + ctx.channel().toString());
        }
    }


    private void addSession(ChannelHandlerContext ctx, DeviceSession session, Integer keepAliveTimer) {

        int type = 0;

        Channel channel = sessionManager.getChannel(session.getClientId());

        if (channel != null && !ctx.channel().equals(channel)) {
            // 同一个设备另外重新
            type = 0;
        } else if (channel != null && ctx.channel().equals(channel)) {
            // 收到重复注册包
            type = 1;
        } else {
            // 新设备注册
            type = 2;
        }

        boolean add = false;

        // 同一个设备另外重新
        // 设备不允许同时上线  用户运行多个端同时上线
        if (type == 0) {
            sessionManager.removeSession(channel);
            LogUtils.e(String.format("重复注册 移除设备：%s 过期的Channel: %s", session.getClientId(), channel.toString()));

            add = true;
        }
        // 收到重复注册包
        else if (type == 1) {
            LogUtils.e("同一个channel重复收到注册包");
        }
        // 新设备或者用户注册
        else {
            add = true;
        }


        if (add) {
            if (keepAliveTimer != null) {
                session.setKeepAliveSeconds(keepAliveTimer);
            }
            session.setChannel(ctx.channel());
            session.setLastPacketTime(new Date());
            sessionManager.addSession(session);
        }
    }
}
